package com.wmtiger.fw
{
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.Timer;

	/**
	 * 全局框架中的帧频管理器
	 * @author wmtiger
	 */	
	public class TickMgr
	{
		private static var _instance:TickMgr;
		
		private var _inited:Boolean = false;
		private var _stage:Stage;
		private var _timer:Timer;
		private var _efVector:Vector.<TickModel>;
		private var _efCount:int = 0;
		private var _timerVector:Vector.<TickModel>;
		private var _timerCount:int = 0;
		
		public function TickMgr()
		{
			_inited = false;
		}

		public static function get instance():TickMgr
		{
			if (_instance == null) 
			{
				_instance = new TickMgr();
			}
			return _instance;
		}
		
		public function init(stage:Stage = null):void
		{
			if(!_inited)
			{
				_stage = stage;
				
				_efVector = new Vector.<TickModel>();
				_timerVector = new Vector.<TickModel>();
				_stage.addEventListener(Event.ENTER_FRAME, onLoop);
				_timer = new Timer(1000);//1s的刷新
				_timer.addEventListener(TimerEvent.TIMER, onTimer);
				_timer.start();
				_inited = true;
			}
		}
		
		protected function onTimer(e:TimerEvent):void
		{
			chkRun(_timerVector);
			_timerCount++;
		}
		
		public function onLoop(e:Event = null):void
		{
			chkRun(_efVector);
			_efCount++;
		}
		
		private function chkRun(v:Vector.<TickModel>):void
		{
			var i:int;
			var l:int = v.length;
			var tm:TickModel;
			var clears:Array = [];
			for (i = l - 1; i >= 0; i--)
			{
				tm = v[i];
				if (tm.disposed)
				{
					clears.push(i);
				}
				else
				{
					tm.update();
				}
			}
			l = clears.length;
			for (i = l - 1; i >= 0; i--)
			{
				v.splice(clears[i], 1);// 将tm从向量中删除
			}
		}
		
		/**
		 * 增加ENTER_FRAME的事件函数
		 * @param fun		事件函数主体
		 * @param delay		事件函数在运行多少帧之后从列表中删除
		 * @param timeOut	事件函数在延迟多少帧后启动
		 * @param args		事件函数需要用到的参数列表
		 */		
		public function addEfHandler(fun:Function, delay:int = -1, timeOut:int = -1, args:Array = null):void
		{
			var tm:TickModel = new TickModel(fun, delay, timeOut, args);
			if (!contains(_efVector, tm))
			{
				_efVector.push(tm);
			}
		}
		
		/**
		 * 增加TIMER的事件函数
		 * @param fun		事件函数主体
		 * @param delay		事件函数在运行多少帧之后从列表中删除
		 * @param timeOut	事件函数在延迟多少帧后启动
		 * @param args		事件函数需要用到的参数列表
		 */
		public function addTimerHandler(fun:Function, delay:int = -1, timeOut:int = -1, args:Array = null):void
		{
			var tm:TickModel = new TickModel(fun, delay, timeOut, args);
			if (!contains(_timerVector, tm))
			{
				_timerVector.push(tm);
			}
		}
		
		private function contains(vector:Vector.<TickModel>, value:TickModel):Boolean
		{
			var len:int = vector.length;
			var i:int;
			
			for(i = len - 1; i > -1; i--)
			{
				if(vector[i] === value)
				{
					return true;
				}
			}
			return false;
		}

	}
}
class TickModel
{
	public var fun:Function;
	public var delay:int;
	public var timeOut:int;
	public var args:Array;
	public var disposed:Boolean;
	public var delayAble:Boolean;
	public var timeOutAble:Boolean;
	
	/**
	 * TickMgr需要的数据模型
	 * @param fun		函数实体
	 * @param delay		函数在运行多少帧/秒之后从列表中删除
	 * @param timeOut	函数在延迟多少帧/秒后启动
	 * @param args		函数需要用到的参数列表
	 */	
	public function TickModel(fun:Function, delay:int = -1, timeOut:int = -1, args:Array = null)
	{
		this.fun = fun;
		this.delay = delay;
		this.timeOut = timeOut;
		this.args = args;
		this.disposed = false;
		this.delayAble = delay <= 0 ? false : true;// 小于等于0的时候，不自动清除
		this.timeOutAble = timeOut <= 0 ? false : true;// 小于等于0的时候，不延迟启动
	}
	
	public function update():void
	{
		if (timeOutAble)
		{
			timeOut--;
			if (timeOut > 0)
			{
				return;
			}
		}
		this.fun.apply(null, args);
		if (delayAble)
		{
			delay--;
			if (delay <= 0)
			{
				dispose();
			}
		}
	}
	
	public function dispose():void
	{
		this.fun = null;
		this.args = null;
		disposed = true;
	}
}